package com.wsoft.interceptor;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.plugins.inner.DataPermissionInterceptor;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.wsoft.constant.DataPermConstant;
import com.wsoft.core.cmd.DataPermSourceService;
import com.wsoft.core.exception.Asserts;
import com.wsoft.core.security.DataPermIgnoreConfig;
import com.wsoft.core.utils.LoginUserUtil;
import com.wsoft.core.utils.SqlAuthDisableHolder;
import com.wsoft.core.utils.SqlAuthOrgHolder;
import com.wsoft.enums.DataPermissionEnum;
import com.wsoft.system.dto.SysDataPermDto;
import com.wsoft.system.entity.SysDataPermEntity;
import com.wsoft.system.service.CommonMyBatisService;
import com.wsoft.system.service.ISysRolePermRelationService;
import com.wsoft.vo.LoginUserDetail;
import lombok.extern.log4j.Log4j;
import net.sf.jsqlparser.JSQLParserException;
import net.sf.jsqlparser.expression.*;
import net.sf.jsqlparser.expression.operators.conditional.AndExpression;
import net.sf.jsqlparser.expression.operators.relational.EqualsTo;
import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
import net.sf.jsqlparser.schema.Column;
import net.sf.jsqlparser.schema.Table;
import net.sf.jsqlparser.statement.Statement;
import net.sf.jsqlparser.statement.select.*;
import net.sf.jsqlparser.util.TablesNamesFinder;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;

import javax.annotation.Resource;
import java.lang.reflect.Field;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

import static com.wsoft.enums.DataPermissionEnum.*;


/**
 * @Author Zhang gukai
 * @Date 2024/10/16 10:48
 */
@Log4j
public class DataPermInterceptor extends DataPermissionInterceptor{


    @Lazy
    @Resource
    private ISysRolePermRelationService rolePermRelationService;


    @Lazy
    @Resource
    private CommonMyBatisService commonMyBatisService;

    @Lazy
    @Resource(name = "hrOrganizationService")
    private DataPermSourceService hrOrganizationService;

    @Lazy
    @Resource(name = "sysOrganizationService")
    private DataPermSourceService sysOrganizationService;

    @Autowired(required = false)
    private DataPermIgnoreConfig dataPermIgnoreConfig;


    @Override
    public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
        if (!SqlAuthDisableHolder.needSqlAuth()) {
            return;
        }
        String firstSql = boundSql.getSql();
        Field field = null;
        Integer i = ThreadContext.getThread();
        if (i != null && i == 1) {
            return;
        }
        // 设置权限过滤标识
        ThreadContext.setThread(1);
        Page page = PageHelper.getLocalPage();
        PageHelper.clearPage();

        try {
            Statement statement = CCJSqlParserUtil.parse(firstSql);
            //获取当前执行sql涉及的表名
            Set<String> mainTables = getMainTable(statement);
            //过滤INFORMATION_SCHEMA
            if(checkInformationSchemaTable(mainTables)){
                return;
            }
            //过滤白名单
            if(checkIgnore(mainTables,dataPermIgnoreConfig.getNames())){
                return;
            }
            //获取用户角色
            LoginUserDetail userInfo = null;
            try {
                 userInfo = LoginUserUtil.getUserInfo();
                if (userInfo == null) {
                    return;
                }
            } catch (Exception e) {
                return;
            }

            field = boundSql.getClass().getDeclaredField("sql");
            field.setAccessible(true);
            //根据流程变量切换组织树
            String process = null;
            if (!SqlAuthOrgHolder.needSwitch()){
                process = DataPermConstant.ORG_PROCESS;
            }
            String authTable = getFirstTableOnField(mainTables);
            if(authTable!=null) {
                try {
                    //获取数据权限
                    Map<String, List<SysDataPermEntity>> map = getDataPermList(userInfo, page, mainTables);
                    List<SysDataPermEntity> result = map.get("result");
                    List<SysDataPermEntity> emptyOrNullList = map.get("emptyOrNullList");
                    //存在数据权限 修改sql
                    if (!result.isEmpty()||!emptyOrNullList.isEmpty()){
                        String newSql = addReTableCondition(statement, userInfo, result, emptyOrNullList,process);
                        //通过反射修改sql语句
                        field.set(boundSql, newSql);
                    }
                } catch (Exception e) {
                    Asserts.fail("数据权限控制失败,请联系管理员");
                    field.set(boundSql, firstSql);
                }
            }
        } catch (JSQLParserException | NoSuchFieldException | IllegalAccessException e) {
            if(StringUtils.isNotEmpty(firstSql)&& ObjectUtils.isNotEmpty(field)){
                try {
                    field.set(boundSql, firstSql);
                } catch (IllegalAccessException illegalAccessException) {
                    illegalAccessException.printStackTrace();
                }
            }
            Asserts.fail("数据异常");
            e.printStackTrace();
        }
        finally {
            ThreadContext.setThread(0);
            PageHelper.setLocalPage(page);
        }
    }
    private Map<String, List<SysDataPermEntity>> getDataPermList(LoginUserDetail userInfo,Page page,Set<String> mainTables){
        Map<String, List<SysDataPermEntity>> perm = new HashMap<>(2);
        //根据用户角色获取数据权限
        List<SysDataPermEntity> dataPermList = new ArrayList<>();
        userInfo.getLoginUserVO().getRoles().forEach(e->{
            List<SysDataPermEntity> result = rolePermRelationService.getDataPermListByRoleId(e.getId());
            dataPermList.addAll(result);
        });
        Function<SysDataPermEntity, String> fieldExtractor = SysDataPermEntity::getTableName;
        Map<Boolean, List<SysDataPermEntity>> splitMap = dataPermList.stream()
                .collect(Collectors.partitioningBy(obj -> fieldExtractor.apply(obj) != null && !fieldExtractor.apply(obj).isEmpty()));
        //指定权限
        List<SysDataPermEntity> nonEmptyList = splitMap.get(true);
        //默认权限
        List<SysDataPermEntity> emptyOrNullList = splitMap.get(false);
        List<SysDataPermEntity> result = new ArrayList<>();
        //匹配当前执行表的数据权限
        for (String e : mainTables) {
            List<SysDataPermEntity> collect = nonEmptyList.stream().filter(item->{
                return item.getTableName().contains(e);
            }).collect(Collectors.toList());
            result.addAll(collect);
        }
        perm.put("result", result.stream().distinct().collect(Collectors.toList()));
        perm.put("emptyOrNullList", emptyOrNullList);
        return perm;
    }

    /**
     * 获取tables的表名
     *
     * @param statement
     * @return
     */
    private Set<String> getMainTable(Statement statement) {
        TablesNamesFinder tablesNamesFinder = new TablesNamesFinder();
        return tablesNamesFinder.getTables((statement));
    }

    /**
     * 记录第一次LocalPage
     * @return
     */
    private Page firstPage(){
    Integer i = ThreadContext.getThread();
    Page page = null;
    if(i == null || i == 0){
        page = PageHelper.getLocalPage() == null?null:(Page)PageHelper.getLocalPage().clone();
    }
    return page;
}
        /**
         * 验证是否包含InformationSchema表
         * @param tables
         * @return
         */
    private boolean checkInformationSchemaTable(Set<String> tables) {
        if(CollectionUtil.isEmpty(tables)){
            return true;
        }
        for (String table : tables) {
            if(table!=null && table.toLowerCase().contains(DataPermConstant.INFORMATION_SCHEMA)){
                return true;
            }

        }
        return false;
    }

    private boolean checkIgnore(Set<String> tables,List<String> names) {
        if(CollectionUtil.isEmpty(tables)){
            return true;
        }
        for (String table : tables) {
            if(table!=null && names.contains(table.toLowerCase())){
                return true;
            }
        }
        return false;
    }
    /**
     * 在原有的sql中增加新的where条件
     */
    private void addWhereCondition(PlainSelect plainSelect, String condition) {
        try {
            final Expression expression = plainSelect.getWhere();
            final Expression envCondition = CCJSqlParserUtil.parseCondExpression(condition);
            if (Objects.isNull(expression)) {
                plainSelect.setWhere(envCondition);
            } else {
                AndExpression andExpression = new AndExpression(expression, envCondition);
                plainSelect.setWhere(andExpression);
            }
        } catch (JSQLParserException e) {
            throw new RuntimeException(e);
        }
    }
    private String getCondition (String tableName,String newTableName ,LoginUserDetail userInfo, List<SysDataPermDto> dtoList, String process) {
        StringBuilder condition = new StringBuilder();
        dtoList.forEach(e -> {
                String sql = getNewSqlByPerm(e, userInfo, tableName,newTableName, process);
                condition.append(sql).append(" or ");
            });

        int index = condition.lastIndexOf(" or");
        String result = "";
        if (index != -1) {
             result = condition.substring(0, index);
        }
        return "".equals(result)?"":"("+result+")";
    }
    private Boolean checkAddCondition(String tableName,String ruleType,String process){
        Set<String> orgRuleTypes = new HashSet<>();
        orgRuleTypes.add(ORG_SELF.getCode());
        orgRuleTypes.add(DataPermissionEnum.ORG_SELF_CHILDREN.getCode());
        orgRuleTypes.add(DataPermissionEnum.ORG_PARENT.getCode());
        orgRuleTypes.add(DataPermissionEnum.ORG_PARENT_CHILDREN.getCode());
        orgRuleTypes.add(DataPermissionEnum.ORG_FREE.getCode());
        orgRuleTypes.add(DataPermissionEnum.ORG_FREE_CHILDREN.getCode());
        orgRuleTypes.add(DataPermissionEnum.ORG_TYPE.getCode());
        orgRuleTypes.add(DataPermissionEnum.ORG_TYPE_CHILDREN.getCode());
        orgRuleTypes.add(DataPermissionEnum.ORG_FREE_UP.getCode());
        orgRuleTypes.add(DataPermissionEnum.ORG_TYPE_UP.getCode());
        orgRuleTypes.add(DataPermissionEnum.ORG_SELF_UP.getCode());
        Set<String> memberRuleTypes = new HashSet<>();
        memberRuleTypes.add(SELF.getCode());
        memberRuleTypes.add(DataPermissionEnum.MEMBER_FREE.getCode());
        // 检查是否为自定义规则
        if (CUSTOMIZE.getCode().equals(ruleType)) {
            return true;
        }
        // 根据 process 确定字段名
        String orgField = DataPermConstant.ORG_PROCESS.equals(process) ?
                DataPermConstant.HR_ORG_ID : DataPermConstant.ORG_ID;
        // 检查组织规则类型
        if (orgRuleTypes.contains(ruleType) && commonMyBatisService.getFieldExists(tableName, orgField) > 0) {
            return true;
        }
        // 检查成员规则类型
        if (memberRuleTypes.contains(ruleType) && commonMyBatisService.getFieldExists(tableName, DataPermConstant.CREATE_BY) > 0) {
            return true;
        }
        return false;
    }
    private String getNewSqlByPerm(SysDataPermDto dto,LoginUserDetail userInfo,String tableName,String newTableName,String process){
        StringBuilder condition = new StringBuilder();
        dto.getRuleValues().forEach(ruleValue->{
            if(checkAddCondition(tableName,ruleValue.getType(),process)){
                String sql = getNewSqlByRuleValue(ruleValue, userInfo, newTableName, process);
                condition.append(sql).append(" and ");
            }
       });
        int index = condition.lastIndexOf(" and");
        String result = "";
        if (index != -1) {
            result = condition.substring(0, index);
        }
        return "".equals(result)?"":result;
    }

    private String getNewSqlByRuleValue(PermRuleValue ruleValue, LoginUserDetail userInfo, String tableName, String process) {
        DataPermissionEnum value = DataPermissionEnum.getByCode(ruleValue.getType());
        Object org = new Object();
        String authOrg = "";
        if (ruleValue.getType().equals(DataPermissionEnum.ORG_PARENT.getCode())
                || ruleValue.getType().equals(DataPermissionEnum.ORG_PARENT_CHILDREN.getCode())
                || ruleValue.getType().equals(DataPermissionEnum.ORG_SELF_CHILDREN.getCode())
                ||ruleValue.getType().equals(DataPermissionEnum.ORG_FREE_CHILDREN.getCode())
                || ruleValue.getType().equals(DataPermissionEnum.ORG_TYPE.getCode())
                ||ruleValue.getType().equals(DataPermissionEnum.ORG_TYPE_CHILDREN.getCode())
                || ruleValue.getType().equals(ORG_FREE_UP.getCode())
                || ruleValue.getType().equals(ORG_TYPE_UP.getCode())
                || ruleValue.getType().equals(ORG_SELF_UP.getCode())) {
            List<Object> orgList = loadDataSource(process);
            org = orgList.stream().filter(e->BeanUtil.getProperty(e, "id").equals(DataPermConstant.ORG_PROCESS.equals(process)?userInfo.getHrOrgId():userInfo.getLoginUserVO().getId())).findFirst().orElse(null);
            if (ruleValue.getType().equals(DataPermissionEnum.ORG_SELF_CHILDREN.getCode())) {
                authOrg = org==null?"":BeanUtil.beanToMap(org,"authCode").get("authCode").toString();
            } else if (ruleValue.getType().equals(DataPermissionEnum.ORG_PARENT.getCode())
                    || ruleValue.getType().equals(DataPermissionEnum.ORG_PARENT_CHILDREN.getCode())) {
                authOrg = getUpOrgByLevel("1", BeanUtil.beanToMap(org,"authCode").get("authCode").toString());
            } else if (ruleValue.getType().equals(DataPermissionEnum.ORG_FREE_CHILDREN.getCode())) {
                if (DataPermConstant.ORG_PROCESS.equals(process)) {
                    authOrg = getOrgFreeChildrenCondition(ruleValue.getValue(), orgList, DataPermConstant.HR_ORGANIZATION);
                } else {
                    authOrg = getOrgFreeChildrenCondition(ruleValue.getValue(), orgList, DataPermConstant.SYS_ORGANIZATION);
                }
            } else if (ruleValue.getType().equals(DataPermissionEnum.ORG_TYPE.getCode())) {
                if (DataPermConstant.ORG_PROCESS.equals(process)) {
                    authOrg =BeanUtil.beanToMap(getOrgByType(ruleValue.getValue(), org, orgList),"hrOrgId").get("hrOrgId").toString();
                } else {
                    authOrg =BeanUtil.beanToMap(getOrgByType(ruleValue.getValue(), org, orgList),"orgId").get("orgId").toString();
                }
            } else if (ruleValue.getType().equals(DataPermissionEnum.ORG_TYPE_CHILDREN.getCode())) {
                    authOrg = BeanUtil.beanToMap(getOrgByType(ruleValue.getValue(), org, orgList),"authCode").get("authCode").toString();
            } else if (ruleValue.getType().equals(ORG_FREE_UP.getCode())
                    || ruleValue.getType().equals(ORG_TYPE_UP.getCode())
                    || ruleValue.getType().equals(ORG_SELF_UP.getCode())) {
                    authOrg = getUpOrg(ruleValue, org, orgList);
            }
            else {
                authOrg = getUpOrgByLevel(ruleValue.getValue(), BeanUtil.beanToMap(org,"authCode").get("authCode").toString());
            }
        }
        //匹配sql片段
        String source = "";
        String field = "";
        Long memberId = userInfo.getLoginUserVO().getId();
        Long data = null;
        if (DataPermConstant.ORG_PROCESS.equals(process)) {
            source = DataPermConstant.HR_ORGANIZATION;
            field = DataPermConstant.HR_ORG_ID;
            if (userInfo.getHrOrgId() == null) {
                data = 0L;
                authOrg = "999";
            } else {
                data = userInfo.getHrOrgId();
            }
        }
        else {
            source= DataPermConstant.SYS_ORGANIZATION;
            field = DataPermConstant.ORG_ID;
            data = userInfo.getLoginUserVO().getLoginOrgId();
        }
        return generateSqlByPermissionType(value, tableName, memberId, source,  field,  data,  authOrg,  ruleValue);
    }

    /**
     * 根据权限类型生成 SQL 片段
     */
    private String generateSqlByPermissionType(DataPermissionEnum value, String tableName, Long memberId ,String source, String field, Long data, String authOrg, PermRuleValue ruleValue) {
        switch (value) {
            case ALL:
                return "";
            case SELF:
                return tableName + ".create_by = " + memberId;
            case ORG_SELF:
                return tableName + "." + field + " = " + data;
            case ORG_SELF_CHILDREN:
                return source + ".auth_code like '" + authOrg + "%'";
            case ORG_PARENT:
                return source + ".auth_code = '" + authOrg + "'";
            case ORG_PARENT_CHILDREN:
                return source + ".auth_code like '" + authOrg + "%'";
            case ORG_FREE:
                return tableName + "." + field + " in(" + ruleValue.getValue() + ")";
            case ORG_FREE_CHILDREN:
                return authOrg;
            case MEMBER_FREE:
                return tableName + ".create_by in(" + ruleValue.getValue() + ")";
            case ORG_TYPE:
                return tableName + "." + field + " = " + authOrg;
            case ORG_TYPE_CHILDREN:
                return source + ".auth_code like '" + authOrg + "%'";
            case CUSTOMIZE:
                List<String> list = JSONUtil.parseArray(ruleValue.getValue()).toList(String.class);
                return tableName + "." + String.join(" ", list);
            case ORG_SELF_UP:
            case ORG_FREE_UP:
            case ORG_TYPE_UP:
                return tableName + "." + field + " in(" + authOrg + ")";
            default:
                return "";
        }
    }

    private  String getUpOrg(PermRuleValue ruleValue,
                                                   Object org,
                                                   List<Object> orgList
                                                   ){
        if (ruleValue.getType().equals(ORG_SELF_UP.getCode())){
                List<Long> parOrgId = getParOrgId(orgList,Long.parseLong(BeanUtil.beanToMap(org,"id").get("id").toString()));
            return StringUtils.join(parOrgId, ",");
        }
        if (ruleValue.getType().equals(ORG_FREE_UP.getCode())){
            String[] split = ruleValue.getValue().split(",");
            List<Long> ids = new ArrayList<>();
            for (String s : split) {
                List<Long> parOrgId = getParOrgId(orgList,Long.parseLong(s));
                ids.addAll(parOrgId);
            }
            return StringUtils.join(ids, ",");
        }
        if (ruleValue.getType().equals(ORG_TYPE_UP.getCode())){
            Object orgByType = getOrgByType(ruleValue.getValue(), org, orgList);
            List<Long> parOrgId = getParOrgId(orgList,Long.parseLong(BeanUtil.beanToMap(orgByType,"id").get("id").toString()));
            return StringUtils.join(parOrgId, ",");
        }
        return "";
    }

    private <T> String getOrgFreeChildrenCondition(String ruleValue,
                                                   List<Object> orgList,
                                                   String orgTableName) {
        String[] split = ruleValue.split(",");
        StringBuilder sb = new StringBuilder();
        int totalItems = split.length;
        int currentIndex = 1;
        for (String s : split) {
            if (currentIndex == totalItems) {
                Object org = orgList.stream().filter(e->BeanUtil.getProperty(e, "id").equals(Long.parseLong(s))).findFirst().get();
                    sb.append(orgTableName + ".auth_code like '" + BeanUtil.beanToMap(org,"authCode").get("authCode").toString() + "%'");
            }
            else {
                Object org = orgList.stream().filter(e->BeanUtil.getProperty(e, "id").equals(Long.parseLong(s))).findFirst().get();
                sb.append(orgTableName + ".auth_code like '" + BeanUtil.beanToMap(org,"authCode").get("authCode").toString() + "%'");
                sb.append(" or ");
                currentIndex++;
            }
        }
        return sb.toString();
    }
    private String getUpOrgByLevel(String level, String orgCode){
        int i = orgCode.length() - Integer.parseInt(level) * 3;
        if (i<=0){
            return orgCode.substring(0,3);
        }
        return orgCode.substring(0,i);
    }

    private Object getOrgByType(String orgType,
                                                  Object org,
                                                  List<Object> orgList){
        Long curOrgId = Long.parseLong(BeanUtil.beanToMap(org,"id").get("id").toString());
        Map<Long, Object> orgParentMap = orgList.stream().collect(Collectors.toMap(e->BeanUtil.getProperty(e, "id"), Function.identity()));
        // 尝试循环加载组织配置
        do {
            // 判断当前组织类型是否与权限组织类型一致
            Long finalCurOrgId = curOrgId;
            List<Object> collect = orgList.stream().filter(o -> BeanUtil.getProperty(o, "id").equals(finalCurOrgId) && BeanUtil.getProperty(o, "type").equals(orgType)).collect(Collectors.toList());
            if (!collect.isEmpty()) {
                return collect.get(0);
            }
            // 否则继续往上一级查找
            curOrgId = Long.parseLong(BeanUtil.beanToMap(orgParentMap.get(curOrgId),"paId").get("paId").toString());

        } while (curOrgId != null && curOrgId.longValue() != 0);
        return org;
    }
    private String addReTableCondition(Statement statement, LoginUserDetail userInfo, List<SysDataPermEntity> result, List<SysDataPermEntity> specificDataPerm,String process) throws Exception {
        Select select = (Select) statement;
        if (select instanceof  SetOperationList) {
            // 判断是否是union查询
            SetOperationList setOperationList = select.getSetOperationList();
            List<Select> selects = setOperationList.getSelects();
            for (int i = 0; i < selects.size(); i++) {
                //遍历赋予权限
                plainSelectPermissions((PlainSelect)selects.get(i),userInfo, result ,specificDataPerm,process);
            }
        } else {
            PlainSelect plainSelect = select.getPlainSelect();
            plainSelectPermissions(plainSelect, userInfo, result, specificDataPerm, process);
        }
        return select.toString();
    }

    private void plainSelectPermissions(PlainSelect plainSelect, LoginUserDetail userInfo, List<SysDataPermEntity> result, List<SysDataPermEntity> specificDataPerm , String process) {
        //1、formItem是不是需要做数据权限
        Object obj = plainSelect.getFromItem();
        if (obj instanceof Select) {
            subSelectPermissions((Select)obj, userInfo , result, specificDataPerm ,process);
        } else if (obj instanceof Table) {
            Table table = (Table) obj;
            String tableName = table.getName();
            //处理默认权限过滤系统表
            List<SysDataPermEntity> entityList = new ArrayList<>();
            if (!result.isEmpty() ){
                entityList = result.stream().filter(e -> {
                    List<String> tableNames = Arrays.asList(e.getTableName().split(","));
                    // 检查 tableNames 是否包含 table.getName()
                    return tableNames.contains(tableName);
                }).collect(Collectors.toList());
            }
            else {
                if (tableName.startsWith(DataPermConstant.SYS_SCHEMA)|| tableName.startsWith(DataPermConstant.TS_SCHEMA)){
                    return;
                }
                entityList = specificDataPerm;
            }

            List<SysDataPermDto> dataPerm = entityList.stream().map(e -> Convert.convert(SysDataPermDto.class, e)).collect(Collectors.toList());
            if (CollUtil.isEmpty(dataPerm)){
                return;
            }
            List<PermRuleValue> ruleValues = new ArrayList<>();
            dataPerm.forEach(e -> {
                JSONArray array = JSONUtil.parseArray(e.getRuleValue());
                List<PermRuleValue> values = JSONUtil.toList(array, PermRuleValue.class);
                e.setRuleValues(values);
                ruleValues.addAll(values);
            });
            //根据主表生成一个新表
            //别名
            Alias alias = table.getAlias();
            String newTableName = ObjUtil.isEmpty(alias)||StrUtil.isBlank(alias.getName()) ? tableName : alias.getName() ;
            String newAlias = ObjUtil.isEmpty(alias)|| StrUtil.isBlank(alias.getName())  ? "" : alias.getName() ;
            String sql = "SELECT " + newTableName + ".* FROM "+ tableName + " " + newAlias;
            try{
            Statement statement = CCJSqlParserUtil.parse(sql);
                Select select = (Select) statement;
                PlainSelect newplainSelect = select.getPlainSelect();
                if (ruleValues.stream().anyMatch(
                        s->s.getType().equals(DataPermissionEnum.ORG_PARENT.getCode())
                                || s.getType().equals(DataPermissionEnum.ORG_PARENT_CHILDREN.getCode())
                                || s.getType().equals(DataPermissionEnum.ORG_SELF_CHILDREN.getCode())
                                || s.getType().equals(DataPermissionEnum.ORG_FREE_CHILDREN.getCode())
                                || s.getType().equals(DataPermissionEnum.ORG_TYPE_CHILDREN.getCode()))) {
                    //绩效模块
                    if (DataPermConstant.ORG_PROCESS.equals(process)){
                        if (commonMyBatisService.getFieldExists(tableName, DataPermConstant.HR_ORG_ID)>0&&!DataPermConstant.HR_ORGANIZATION.equals(table.getName())){
                            modifyTable(newplainSelect, table,process);
                        }
                    }
                    //基础模块
                    else {
                        if (commonMyBatisService.getFieldExists(tableName, DataPermConstant.ORG_ID)>0&&!DataPermConstant.SYS_ORGANIZATION.equals(tableName)){
                            modifyTable(newplainSelect, table,null);
                        }
                    }
                }
                String condition = getCondition(tableName, newTableName, userInfo, dataPerm, process);
                if (!condition.isEmpty()) {
                    // 获取主表名和别名
                    addWhereCondition(newplainSelect, condition);
                    plainSelect.setFromItem(new Table("("+newplainSelect.toString()+") "+newTableName));
                }
            } catch (Exception e) {
                return;
            }
            }
        }


    /**
     * 为 HAVING 条件中的字段添加表名前缀
     *
     * @param plainSelect SELECT 语句对象
     * @param tableName   表名
     */
    private static void addTablePrefixToHaving(PlainSelect plainSelect, String tableName) {
        if (plainSelect == null || tableName == null || tableName.isEmpty()) {
            return; // 如果 plainSelect 或 tableName 为空，直接返回
        }

        // 获取 HAVING 条件
        Expression having = plainSelect.getHaving();
        if (having == null) {
            return; // 如果 HAVING 条件为空，直接返回
        }

        // 递归处理 HAVING 条件中的表达式
        processExpression(having, tableName);
    }

    /**
     * 递归处理表达式，为其中的字段添加表名前缀
     *
     * @param expression 表达式
     * @param tableName  表名
     */
    private static void processExpression(Expression expression, String tableName) {
        if (expression instanceof Column) {
            // 如果表达式是字段，且没有表名前缀，则添加表名前缀
            Column column = (Column) expression;
            if (column.getTable() == null) {
                column.setTable(new Table(tableName));
            }
        } else if (expression instanceof BinaryExpression) {
            // 如果表达式是二元表达式（如 AND、OR、= 等），递归处理左右两边的表达式
            BinaryExpression binaryExpression = (BinaryExpression) expression;
            processExpression(binaryExpression.getLeftExpression(), tableName);
            processExpression(binaryExpression.getRightExpression(), tableName);
        } else if (expression instanceof net.sf.jsqlparser.expression.Function) {
            // 如果表达式是函数，递归处理函数的参数
            net.sf.jsqlparser.expression.Function function = (net.sf.jsqlparser.expression.Function) expression;
            ExpressionList<?> parameters = function.getParameters();
            for (Expression param : parameters) {
                processExpression(param, tableName);
            }
        } else if (expression instanceof Parenthesis) {
            // 如果表达式是括号表达式，递归处理括号内的表达式
            Parenthesis parenthesis = (Parenthesis) expression;
            processExpression(parenthesis.getExpression(), tableName);
        }
        // 其他类型的表达式可以根据需要继续扩展
    }

    /**
     * 为 ORDER BY 子句中的字段添加表名前缀
     *
     * @param plainSelect SELECT 语句对象
     * @param tableName   表名
     */
    private static void addTablePrefixToOrderBy(PlainSelect plainSelect, String tableName) {
        if (plainSelect == null || tableName == null || tableName.isEmpty()) {
            return; // 如果 plainSelect 或 tableName 为空，直接返回
        }

        // 获取 ORDER BY 子句
        List<OrderByElement> orderByElements = plainSelect.getOrderByElements();
        if (orderByElements == null || orderByElements.isEmpty()) {
            return; // 如果 ORDER BY 子句为空，直接返回
        }

        for (OrderByElement orderByElement : orderByElements) {
            Expression expression = orderByElement.getExpression();
            if (expression instanceof Column) {
                Column column = (Column) expression;
                if (column.getTable() == null) {
                    column.setTable(new Table(tableName));
                }
            }
        }
    }


    /**
     * 为 GROUP BY 子句中的字段添加表名前缀
     *
     * @param plainSelect SELECT 语句对象
     * @param tableName   表名
     */
    private static void addTablePrefixToGroupBy(PlainSelect plainSelect, String tableName) {
        if (plainSelect == null || tableName == null || tableName.isEmpty()) {
            return; // 如果 plainSelect 或 tableName 为空，直接返回
        }

        // 获取 GROUP BY 子句
        GroupByElement groupBy = plainSelect.getGroupBy();
        if (groupBy == null || groupBy.getGroupByExpressionList() == null || groupBy.getGroupByExpressionList().isEmpty()) {
            return; // 如果 GROUP BY 子句为空，直接返回
        }

        for (Object o : groupBy.getGroupByExpressionList()) {
            if (o instanceof Column) {
                Column column = (Column) o;
                if (column.getTable() == null) {
                    column.setTable(new Table(tableName));
                }
            }

        }
    }

    /**
     * 为 JOIN 条件中的字段添加表名前缀
     *
     * @param plainSelect SQL 解析对象
     * @param tableName   主表名
     * @param alias       主表别名
     */
    private void addTablePrefixToJoins(PlainSelect plainSelect, String tableName, String alias) {
        List<Join> joins = plainSelect.getJoins();
        if (joins != null) {
            for (Join join : joins) {
                Expression onExpression = join.getOnExpression();
                if (onExpression != null) {
                    onExpression.accept(new ExpressionVisitorAdapter() {
                        @Override
                        public void visit(Column column) {
                            if (column.getTable() == null) {
                                column.setTable(new Table(tableName, alias));
                            }
                        }
                    });
                }
            }
        }
    }

    private void subSelectPermissions(Select subselect, LoginUserDetail userInfo, List<SysDataPermEntity> result, List<SysDataPermEntity> specificDataPerm , String process) {
        if (subselect.getSetOperationList() != null) {
            SetOperationList setOperationList = subselect.getSetOperationList();
            List<Select> selects = setOperationList.getSelects();
            for (int i = 0; i < selects.size(); i++) {
                //遍历赋予权限
                plainSelectPermissions((PlainSelect)selects.get(i),userInfo, result ,specificDataPerm,process);
            }
        } else {
            PlainSelect plainSelect = subselect.getPlainSelect();
            //赋予权限
            plainSelectPermissions(plainSelect,userInfo, result ,specificDataPerm,process);
        }
    }

    /**
     *根据权限修改sql
     */
    private void modifyTable(PlainSelect plainSelect, Table table ,String process) {
        String tableName = table.getName();
        String tableAlias = table.getAlias() != null ? table.getAlias().getName() : null;
        Table organizationTable = new Table();
        Column mainTableColumn = new Column();
        if (DataPermConstant.ORG_PROCESS.equals(process)){
            organizationTable = new Table(DataPermConstant.HR_ORGANIZATION);
            mainTableColumn= new Column(DataPermConstant.HR_ORG_ID);
        }
        else {
            organizationTable = new Table(DataPermConstant.SYS_ORGANIZATION);
            mainTableColumn = new Column(DataPermConstant.ORG_ID);
        }
        // 设置主表的列和表名（如果有别名则使用别名）
        Table mainTable = new Table(tableAlias != null ? tableAlias : tableName.trim());
        mainTableColumn.setTable(mainTable);
            Column orgTableColumn = new Column(DataPermConstant.ID);
            orgTableColumn.setTable(organizationTable);

            EqualsTo equalsTo = new EqualsTo();
            equalsTo.setLeftExpression(mainTableColumn);
            equalsTo.setRightExpression(orgTableColumn);
            // 创建JOIN对象
            Join newJoin = new Join();
            newJoin.setLeft(true);
            newJoin.setRightItem(organizationTable);
            newJoin.addOnExpression(equalsTo);
            // 添加新的 JOIN 到原始 SELECT 语句
            plainSelect.addJoins(newJoin);
    }

    /**
     * 获取拥有字段的指定第一张表
     *
     * @return
     */
    private  String getFirstTableOnField(Set<String> tables) {
        if(CollectionUtil.isEmpty(tables)){
            return null;
        }
        for (String table : tables) {
            if(commonMyBatisService.getFieldExists(table.toLowerCase(), DataPermConstant.ORG_ID)>0
            || commonMyBatisService.getFieldExists(table.toLowerCase(), DataPermConstant.CREATE_BY)>0
              ||  commonMyBatisService.getFieldExists(table.toLowerCase(), DataPermConstant.HR_ORG_ID)>0){
                return table;
            }
        }
        return null;
    }
    private List<Object> loadDataSource(String process) {
        Map<String, List<Object>> map = new HashMap<>();
        if (process.equals(DataPermConstant.ORG_PROCESS)) {
            return hrOrganizationService.loadDataSource();
        }
        return sysOrganizationService.loadDataSource();
    }
    /**
     * 递归查找上级组织
     */
    private List<Long> getParOrgId(List<Object> list,Long curOrgId) {
        List<Long> resultList = new ArrayList<>();
        //递归
        recursionOrg(list,curOrgId,resultList);
        return resultList;
    }

    private void recursionOrg(List<Object> list,
                              Long orgId,
                              List<Long> resultList){
        List<Object> collect =
                list.stream().filter(item -> orgId.equals(BeanUtil.getProperty(item, "id"))).collect(Collectors.toList());
        if(CollUtil.isNotEmpty(collect)){
            resultList.add(Long.parseLong(BeanUtil.beanToMap(collect.get(0),"id").get("id").toString()));
            recursionOrg(list,Long.parseLong(BeanUtil.beanToMap(collect.get(0),"paId").get("paId").toString()),resultList);
        }
        }


    private void addTablePrefixToColumns(PlainSelect plainSelect, String tableName) {
        // 获取 SELECT 语句中的所有字段
        List<SelectItem<?>> selectItems = plainSelect.getSelectItems();
        if (selectItems == null || selectItems.isEmpty()) {
            return; // 如果字段列表为空，直接返回
        }

        for (SelectItem selectItem : selectItems) {
            // 获取字段的表达式
            Expression expression = selectItem.getExpression();

            // 如果字段是 Column 类型，则为其添加表名前缀
            if (expression instanceof Column) {
                Column column = (Column) expression;
                if (column.getTable() == null) {
                        column.setTable(new Table(tableName));
                }
            }
        }
    }
        /**
        * 为 WHERE 条件中的字段添加表名前缀
        * @param plainSelect
        * @param tableName
        */
    private void addTablePrefixToWhere(PlainSelect plainSelect, String tableName) {
        Expression where = plainSelect.getWhere();
        if (where != null) {
            where.accept(new ExpressionVisitorAdapter() {
                @Override
                public void visit(Column column) {
                    if (column.getTable() == null) {
                        column.setTable(new Table(tableName));
                    }
                }
            });
        }
    }

    }




